package com.iot.common.security.aop;

import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import com.alibaba.fastjson.JSONObject;
import com.iot.common.core.constant.SecurityConstants;
import com.iot.common.security.domain.SimpleUser;
import com.iot.common.security.feign.SecurityOauthService;
import com.nimbusds.jwt.SignedJWT;

import lombok.RequiredArgsConstructor;

@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
@RequiredArgsConstructor
@Component
public class SecurityAuthorizationAop {

	private final SecurityOauthService securityOauthFeign;

	@Pointcut("@annotation(com.iot.common.security.annotation.SecurityAuthorization)")
	private void authorization() {
	}

	@Around("authorization()")
	public Object authorization(ProceedingJoinPoint point) throws Throwable {
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = (HttpServletRequest) requestAttributes
				.resolveReference(RequestAttributes.REFERENCE_REQUEST);
		String token = request.getHeader(SecurityConstants.TOKEN_HEADER);
		securityOauthFeign.check_token(token);
		try {
			token = token.replace(SecurityConstants.TOKEN_PREFIX, "");
			SignedJWT jwt = SignedJWT.parse(token);
			Object account = jwt.getJWTClaimsSet().getClaim("payload");
			if (account != null) {
				SimpleUser user = JSONObject.parseObject(account.toString(), SimpleUser.class);
				SecurityContextHolder.getContext().setAuthentication(
						new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()));
			}
		} catch (Exception e) {
		}
		return point.proceed();
	}

}
